package com.sunday.authorization.mock.oauth2.client.web;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.reactive.function.client.WebClient;

import static org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient;

@RequiredArgsConstructor
@Controller
@Slf4j
public class OAuthClientController {

    private final WebClient webClient;


    /**
     * 客户端模式示例
     * @param model
     * @param authorizedClient
     * @return
     */
    @ResponseBody
    @GetMapping("clientSecretBasic")
    public Object clientSecretBasic(Model model, @RegisteredOAuth2AuthorizedClient("clientSecretBasic") OAuth2AuthorizedClient authorizedClient) {
        log.info("登录成功!");
        String result = webClient.get().uri("http://localhost:8060/message/msg")
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .retrieve() //从这个方法以后就开始处理http响应了
                .bodyToMono(String.class)
                .block();
        return STR."\{result}<br/>\{authorizedClient.getAccessToken()}";
    }

    /**
     * 客户端模式示例
     * @param model
     * @param authorizedClient
     * @return
     */
    @ResponseBody
    @GetMapping("clientSecretPost")
    public Object clientSecretPost(Model model, @RegisteredOAuth2AuthorizedClient("clientSecretPost") OAuth2AuthorizedClient authorizedClient) {
        log.info("登录成功!");
        String result = webClient.get().uri("http://localhost:8060/message/msg")
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .retrieve() //从这个方法以后就开始处理http响应了
                .bodyToMono(String.class)
                .block();
        return STR."\{result}<br/>\{authorizedClient.getAccessToken()}";
    }

    /**
     * client-authentication-method=none，将自动开启PKCE
     * 授权码模式认证示例1
     *
     * https://docs.spring.io/spring-security/reference/servlet/integrations/mvc.html#mvc-authentication-principal
     * https://docs.spring.io/spring-security/reference/reactive/oauth2/client/authorized-clients.html#oauth2Client-registered-authorized-client
     *
     * @param model
     * @param authorizedClient
     * @param oauth2User
     * @return
     */
    @ResponseBody
    @GetMapping("home")
    public String home(Model model, @RegisteredOAuth2AuthorizedClient("authcode") OAuth2AuthorizedClient authorizedClient,
                       @AuthenticationPrincipal OAuth2User oauth2User) {
        log.info(STR."====== access token ====== \{authorizedClient.getAccessToken().getTokenValue()}");
        log.info(STR."====== refresh token ====== \{authorizedClient.getRefreshToken() == null ? null : authorizedClient.getRefreshToken().getTokenValue()}");
        log.info(STR."登录成功!\n用户名:\{oauth2User.getName()}");
        model.addAttribute("access token", authorizedClient.getAccessToken().getTokenValue());
        model.addAttribute("refresh token", authorizedClient.getRefreshToken() == null ? null : authorizedClient.getRefreshToken().getTokenValue());
        model.addAttribute("userName", oauth2User.getName());
        return STR."userName：\{oauth2User.getName()}<br/>[access token]<br/>\{authorizedClient.getAccessToken().getTokenValue()}<br/>[refresh token]<br/>\{authorizedClient.getRefreshToken() == null ? null : authorizedClient.getRefreshToken().getTokenValue()}";
    }

    @ResponseBody
    @GetMapping("home1")
    public String home1(Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient) {
        log.info("{}", authorizedClient);
        return "2333";
    }




}
